﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
using Tank90.Properties;

namespace Tank90
{
    /// <summary>
    ///     Class MainManager.
    /// </summary>
    internal class MainManager
    {
        /// <summary>
        ///     The _main manager
        /// </summary>
        private static MainManager _mainManager;

        public bool IsLose = false;

        /// <summary>
        ///     The _ graphics
        /// </summary>
        private static Graphics _Graphics;

        /// <summary>
        ///     The tank count
        /// </summary>
        private readonly int TANKCOUNT = 30;

        /// <summary>
        ///     The enemies list
        /// </summary>
        private readonly List<Enemy> enemiesList = new List<Enemy>();

        /// <summary>
        ///     The equipment
        /// </summary>
        private readonly Equipment equipment = new Equipment();

        /// <summary>
        ///     The now enemies
        /// </summary>
        private readonly List<Enemy> nowEnemies = new List<Enemy>();

        private List<Blast> blasts=new List<Blast>(); //爆炸
         
        private List<Born> borns=new List<Born>(); 
        /// <summary>
        ///     The random
        /// </summary>
        private readonly Random random = new Random();

        /// <summary>
        ///     The x location
        /// </summary>
        private readonly int[] xLocation = {0, 320, 580};

        private int EnemyDieCount = 0;
        private int EquipTime;

        private bool IsEnemyAllDied;

        private bool IsEnemyStatic; //是否全部静止

        private bool IsEquipMent; //是否已经碰撞到装备

        /// <summary>
        ///     The is first enemy born
        /// </summary>
        private bool IsFirstEnemyBorn = false;

        /// <summary>
        ///     The is initiate
        /// </summary>
        private bool IsInitiate;

        private bool IsPlayerEnemyLess;

        /// <summary>
        ///     The is win
        /// </summary>
        private bool IsWin; //是否已经消灭全部敌人

        /// <summary>
        ///     The maps
        /// </summary>
        public List<Map> Maps = new List<Map>();

        /// <summary>
        ///     The show equipment
        /// </summary>
        private bool ShowEquipment; //是否显示装备

        /// <summary>
        ///     The enemy count
        /// </summary>
        private int enemyCount;

        /// <summary>
        ///     The player tank
        /// </summary>
        public PlayerTank playerTank = new PlayerTank(200, 600);

        /// <summary>
        ///     The show time
        /// </summary>
        private int showTime; //装备闪动次数

        /// <summary>
        ///     Prevents a default instance of the <see cref="MainManager" /> class from being created.
        /// </summary>
        private MainManager()
        {
        }

        /// <summary>
        ///     Gets the main manager.
        /// </summary>
        /// <value>The main manager.</value>
        public static MainManager mainManager
        {
            get
            {
                if (_mainManager == null)
                    lock (typeof (MainManager)) //多线程中共享资源同步
                        if (_mainManager == null)
                            _mainManager = new MainManager();
                return _mainManager;
            }
        }

        /// <summary>
        ///     Gets the star.
        /// </summary>
        /// <param name="graphics">The graphics.</param>
        public void GetStar(Graphics graphics, out int enemycount, out int playerLife)
        {
            _Graphics = graphics;
            if (IsLose)
            {
                _Graphics.DrawImage(Resources.GameOver,new Point(100,100));
                enemycount = 0;
                playerLife = 0;
                return;
            }
            if (!IsInitiate)
            {
                InitiatePlayer(graphics);
                InitiateEnemyList();
                IsInitiate = true;
            }

            LoadMap();

            SetNowEnemy();
            playerTank.Drawing(graphics);

       
            IsCrash();
            DrawGameElement();
            if (ShowEquipment)
            {
                if ((showTime - 1)%5 == 0 || showTime%5 == 0 ||
                    (showTime + 1)%5 == 0)
                {
                    equipment.Drawing(_Graphics);
                }
                showTime++;
                if (showTime > 2000)
                {
                    ShowEquipment = false;
                    IsPlayerEnemyLess = false;
                    EquipTime = 0;
                    equipment.Death();
                }
            }
            enemycount = TANKCOUNT - enemyCount;
            playerLife = playerTank.life;
        }

        /// <summary>
        ///     Moves the specified key.
        /// </summary>
        /// <param name="key">The <see cref="KeyEventArgs" /> instance containing the event data.</param>
        public void Move(KeyEventArgs key)
        {
            //IsEnemyAllDied = true;
            int oldx = playerTank.x, oldy = playerTank.y;
            playerTank.Move(key);

            #region //玩家与敌人碰撞

            foreach (Enemy enemy in nowEnemies)
            {
                if (playerTank.GetRectangle().IntersectsWith(enemy.GetRectangle()))
                {
                    playerTank.x = oldx;
                    playerTank.y = oldy;
                }
            }

            #endregion

            #region 玩家与地图相撞

            foreach (Map map in Maps)
            {
                if (playerTank.GetRectangle().IntersectsWith(map.GetRectangle()))
                {
                    if (map.Transparent >= 3)
                    {
                        playerTank.x = oldx;
                        playerTank.y = oldy;
                    }
                }
            }

            #endregion

            if (playerTank.GetRectangle().IntersectsWith(equipment.GetRectangle()))
            {
                Sound.Play("eqiup");
                GetEquipment();
                ShowEquipment = false; //碰撞后消失
                equipment.Death();
            }
        }


        private void GetEquipment()
        {
            IsEquipMent = true;
            playerTank.speed += 4;
            switch (equipment.enquipType)
            {
                case EquipType.EquipEnemyless:
                    IsPlayerEnemyLess = true;
                    break;
                case EquipType.EnemyBlast:
                    IsEnemyAllDied = true;
                    break;
                case EquipType.AddLife:
                    playerTank.life++;
                    break;
                case EquipType.AddPower:
                    playerTank.BulletPower++;
                    playerTank.BulletSpeed += 5;
                    break;
                case EquipType.EnemyStatic:
                    IsEnemyStatic = true;
                    break;
            }
        }

        /// <summary>
        ///     Crashes this instance.
        /// </summary>
        private void Crash()
        {
        }

        /// <summary>
        ///     Intimates the player.
        /// </summary>
        /// <param name="graphics">The graphics.</param>
        private void InitiatePlayer(Graphics graphics)
        {
            AddGameElement(new Born(playerTank.x, playerTank.y-20));
            playerTank.life = 3;
            playerTank.speed = 4;
            playerTank.Drawing(graphics);
        }

        /// <summary>
        ///     Initiates the enemy list.
        /// </summary>
        private void InitiateEnemyList()
        {
            for (int i = 0; i < TANKCOUNT/3; i++) //定义坦克的总数量
            {
                //设定位置参数
                var enemyF = new Enemy(playerTank);
                enemyF.EnemyType = 1;
                enemyF.x = xLocation[0]; //random.Next(0, 2)];
                if (random.Next(0, 10) < 2)
                {
                    enemyF.IsRed = true;
                }
                enemiesList.Add(enemyF);
                var enemyS = new Enemy(playerTank);
                enemyS.EnemyType = 2;
                enemyS.x = xLocation[1];
                ; //xLocation[random.Next(0, 2)];
                if (random.Next(0, 10) < 2)
                {
                    enemyS.IsRed = true;
                }
                enemiesList.Add(enemyS);
                var enemyT = new Enemy(playerTank);
                enemyT.EnemyType = 3;
                enemyT.x = xLocation[2]; //xLocation[random.Next(0, 2)];
                if (random.Next(0, 10) < 2)
                {
                    enemyT.IsRed = true;
                }
                enemiesList.Add(enemyT);
            }
        }

        /// <summary>
        ///     Loads the map.
        /// </summary>
        private void LoadMap()
        {
            foreach (Map map in Maps)
            {
                if (!map.elemenType.Equals(MapElemenType.None))
                {
                    map.Drawing(_Graphics);
                }
            }
        }

        /// <summary>
        ///     Creats the enemy thead.
        /// </summary>
        private void CreatEnemyThead()
        {
            var enemyThread = new Thread(IsCrash);
            enemyThread.Start();
        }


        /// <summary>
        ///     Determines whether this instance is crash.
        /// </summary>
        private void IsCrash()
        {
            #region //装备碰撞后结果

            if (IsEquipMent)
            {
                EquipTime++;
                for (int j = 0; j < 3; j++)
                {
                    if (IsEnemyAllDied)
                    {
                        Sound.Play("blast.wav");
                        nowEnemies[nowEnemies.Count - 1].IsDied = true;
                        AddGameElement(new Blast(nowEnemies[nowEnemies.Count - 1].x,nowEnemies[nowEnemies.Count - 1].y));
                        nowEnemies.Remove(nowEnemies[nowEnemies.Count - 1]);
                    }
                    if (IsEnemyStatic)
                    {
                        nowEnemies[j].IsMove = false;
                        nowEnemies[j].IsFire = false; //不能发子弹
                    }
                    else if (EquipTime > 2000)
                    {
                        nowEnemies[j].IsMove = true;
                        nowEnemies[j].IsFire = true; //不能发子弹
                    }
                }

                IsEnemyStatic = false;
                IsEnemyAllDied = false;
            }

            #endregion

            if (EquipTime > 2000)
            {
                EquipTime = 0;
                IsPlayerEnemyLess = false;
            }
            for (int j = 0; j < nowEnemies.Count; j++)
            {
                int oldx = nowEnemies[j].x, oldy = nowEnemies[j].y;
                nowEnemies[j].Drawing(_Graphics);

                #region  //玩家与敌人

                if (nowEnemies[j].GetRectangle().IntersectsWith(playerTank.GetRectangle()))
                {
                    switch (nowEnemies[j].directions)
                    {
                        case Directions.Up:
                            nowEnemies[j].y = oldy + 1;// bricks[k].y + bricks[k].Height;
                            break;
                        case Directions.Down:
                            nowEnemies[j].y = oldy - 1; //bricks[k].y - bricks[k].Height;
                            break;
                        case Directions.Left:
                            nowEnemies[j].x = oldx + 1;//bricks[k].x + bricks[k].Width;
                            break;
                        case Directions.Right:
                            nowEnemies[j].x = oldx - 1; //bricks[k].x - bricks[k].Width;
                            break;
                    }
                    if (random.Next(0, 10) < 8)
                    {
                        nowEnemies[j].GetDirection();
                    }
                }

                #endregion

                #region  //敌人与敌人

                foreach (Enemy enemy1 in nowEnemies)
                {
                    if (!nowEnemies[j].Equals(enemy1))
                    {
                        if (nowEnemies[j].GetRectangle().IntersectsWith(enemy1.GetRectangle()))
                        {
                            switch (nowEnemies[j].directions)
                            {
                                case Directions.Up:
                                    nowEnemies[j].y = oldy + 1;// bricks[k].y + bricks[k].Height;
                                    break;
                                case Directions.Down:
                                    nowEnemies[j].y = oldy - 1; //bricks[k].y - bricks[k].Height;
                                    break;
                                case Directions.Left:
                                    nowEnemies[j].x = oldx + 1;//bricks[k].x + bricks[k].Width;
                                    break;
                                case Directions.Right:
                                    nowEnemies[j].x = oldx - 1; //bricks[k].x - bricks[k].Width;
                                    break;
                            }
                            if (random.Next(0, 10) < 8)
                            {
                                nowEnemies[j].AdjustDirections();
                            }
                        }
                    }
                }

                #endregion

                for (int i = 0; i < Maps.Count; i++)
                {
                    #region//敌人与元素

                    if (nowEnemies[j].GetRectangle().IntersectsWith(Maps[i].GetRectangle()))
                    {
                        if (Maps[i].Transparent >= 3)
                        {
                            switch (nowEnemies[j].directions)
                            {
                                case Directions.Up:
                                    nowEnemies[j].y = oldy + 1;// bricks[k].y + bricks[k].Height;
                                    break;
                                case Directions.Down:
                                    nowEnemies[j].y = oldy - 1; //bricks[k].y - bricks[k].Height;
                                    break;
                                case Directions.Left:
                                    nowEnemies[j].x = oldx + 1;//bricks[k].x + bricks[k].Width;
                                    break;
                                case Directions.Right:
                                    nowEnemies[j].x = oldx-1; //bricks[k].x - bricks[k].Width;
                                    break;
                            }
                            if (random.Next(0, 10) < 8)
                            {
                                nowEnemies[j].AdjustDirections();
                            }
                        }
                    }

                    #endregion

                    #region//敌人子弹与地图元素

                    if (nowEnemies[j].Bullet != null && Maps[i].Transparent > 0)
                        //||!map.elemenType.Equals(MapElemenType.None)))
                    {
                        if (nowEnemies[j].Bullet.GetRectangle().IntersectsWith(Maps[i].GetRectangle()))
                        {
                            if (Maps[i].Transparent > 3)
                            {
                                nowEnemies[j].BulletDeath();
                                if (Maps[i].Transparent == 4 || Maps[i].Type.Equals(MapElemenType.OBrick))
                                {
                                   // Sound.Play("CrashBrick");
                                    Maps[i].Death();
                                }
                                else
                                {
                                  //  Sound.Play("hit");
                                }
                            }
                        }
                    }

                    #endregion

                    #region 玩家子弹与地图元素

                    if (playerTank.Bullet != null && Maps[i].Transparent > 0)
                        //||!map.elemenType.Equals(MapElemenType.None)))
                    {
                        if (Maps[i].GetRectangle().IntersectsWith(playerTank.Bullet.GetRectangle()))
                        {
                            if (playerTank.Bullet.power > 2 && Maps[i].Transparent > 3) //power=3能够消灭石头
                            {
                                playerTank.BulletDeath();
                                Maps[i].elemenType = MapElemenType.None;
                            }
                            else if (Maps[i].Transparent > 3)
                            {
                                playerTank.BulletDeath(); //想想激光子弹怎么写

                                if (Maps[i].Transparent == 4 || Maps[i].Type.Equals(MapElemenType.OBrick))
                                {
                                    Sound.Play("CrashBrick");
                                    Maps[i].Death();
                                }
                                else if (playerTank.BulletPower<2)
                                {
                                    Sound.Play("hit");
                                }
                                else
                                {

                                    Sound.Play("CrashBrick");
                                    
                                }
                               
                            }
                        }
                    }

                    #endregion
                }

                #region//玩家子弹与敌人碰撞

                //foreach (Enemy nowEnemy in nowEnemies)

                if (playerTank.Bullet != null)
                {
                    if (nowEnemies[j].GetRectangle().Contains(new Point(playerTank.Bullet.x, playerTank.Bullet.y)))
                    {
                        Sound.Play("hit.wav");
                        if (nowEnemies[j].IsRed)
                        {
                            equipment.enquipType = (EquipType) random.Next(0, 5); //设定装备类型
                            ShowEquipment = true;
                            nowEnemies[j].IsRed = false;
                        }
                        nowEnemies[j].life--;
                        playerTank.BulletDeath();
                        if (nowEnemies[j].life <= 0)
                        {
                            Sound.Play("blast.wav");
                            nowEnemies[j].IsDied = true;
                            AddGameElement(new Blast(nowEnemies[j].x,nowEnemies[j].y));
                            nowEnemies.Remove(nowEnemies[j]);

                            break;
                        }
                    }

                    //子弹与子弹碰撞
                    if (nowEnemies[j].Bullet != null && playerTank.Bullet != null)
                    {
                        if (
                            nowEnemies[j].Bullet.GetRectangle()
                                .Contains(new Point(playerTank.Bullet.x, playerTank.Bullet.y)) ||
                            playerTank.Bullet.GetRectangle()
                                .Contains(new Point(nowEnemies[j].Bullet.x, nowEnemies[j].Bullet.y)))
                        {
                            Sound.Play("CrashBrick.wav");
                            nowEnemies[j].BulletDeath();
                            playerTank.BulletDeath();
                        }
                    }
                }

                //敌人子弹与玩家碰撞
                if (nowEnemies[j].Bullet != null)
                {
                    if (playerTank.GetRectangle().Contains(new Point(nowEnemies[j].Bullet.x, nowEnemies[j].Bullet.y)))
                    {
                        int life;
                        nowEnemies[j].BulletDeath();
                        if (!IsPlayerEnemyLess) //是不是无敌
                        {
                            Sound.Play("blast.wav");
                            playerTank.life--;
                            life = playerTank.life;
                            playerTank.IsDied = true;
                            playerTank.dirImage = null;
                            AddGameElement(new Blast(playerTank.x, playerTank.y));
                            if (playerTank.life <= 0)
                            {
                                IsLose = true;
                         
                            }
                            else
                            {
                                playerTank = new PlayerTank(200, 600);
                                playerTank.life = life;
                                playerTank.speed = 4;
                                AddGameElement(new Born(playerTank.x, playerTank.y));
                            }
                        }
                    }
                }

                #endregion
            }
        }


        /// <summary>
        ///     Sets the now enemy.
        /// </summary>
        private void SetNowEnemy()
        {
            while (nowEnemies.Count < 3 && enemyCount < TANKCOUNT)
            {
                AddGameElement(new Born(enemiesList[enemyCount].x-10, enemiesList[enemyCount].y));
                nowEnemies.Add(enemiesList[enemyCount]); //产生3个位置不一样的敌人
                enemyCount++;
            }

            if (enemyCount == TANKCOUNT && nowEnemies.Count == 0)
            {
                IsWin = true;
                enemyCount++;
            }
            if (IsWin)
            {
                IsWin = false;
                MessageBox.Show("you are win!");
            }
        }

        /// <summary>
        ///     Sets the map.
        /// </summary>
        /// <param name="maps">The maps.</param>
        public void setMap(List<Map> maps)
        {
            Maps = maps;
        }

        private void DrawGameElement()
        {
            for (int i = 0; i < borns.Count; i++)
            {
                borns[i].Drawing(_Graphics);
            }
            for(int i=0;i<blasts.Count;i++)
            {
                blasts[i].Drawing(_Graphics);
            }
        }

        public void AddGameElement(Element e)
        {
            if (e is Born)
            {
                borns.Add(e as Born);
            }
            if (e is Blast)
            {
                blasts.Add(e as Blast);
            }
        }

        public void DelGameElement(Element e)
        {
            if (e is Born)
            {
                borns.Remove(e as Born);
            }
            if (e is Blast)
            {
                blasts.Remove(e as Blast);
            }
          
        }
    }
}